package com.tju.resource.business.doc;

import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tju.resource.annotation.Log;
import com.tju.resource.business.sys.SysPermissionServiceImpl;
import com.tju.resource.common.ServiceException;
import com.tju.resource.mapper.DocContentMapper;
import com.tju.resource.model.DocContent;
import com.tju.resource.model.SysPermission;
import com.tju.resource.model.log.OperationLogTool;
import com.tju.resource.tool.bcrypt.BCryptPasswordEncoderUtil;
import com.tju.resource.tool.digital_conversion.NumbersToChinese;
import com.tju.resource.tool.enum_utils.FunctionType;
import com.tju.resource.tool.enum_utils.SizeConverter;
import com.tju.resource.result.ResultUtil;
import com.tju.resource.tool.tool.*;
import com.tju.resource.yml_config.YmlConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import wiki.xsx.core.pdf.component.XEasyPdfComponent;
import wiki.xsx.core.pdf.doc.*;
import wiki.xsx.core.pdf.handler.XEasyPdfHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

import com.tju.resource.result.Result;
import com.tju.resource.result.ResultEnum;

import static com.tju.resource.common.GlobalCall.*;
import static com.tju.resource.tool.img.ImgUtils.*;

/**
 * 文档实现
 *
 * @Author CLS
 * @Date 2022/2/28 11:27
 */
@Slf4j
@Service
public class DocUserPermServiceImp implements DocUserPermService {

    @Autowired
    private DocContentMapper docContentMapper;
    @Autowired
    private YmlConfig ymlConfig;
    @Autowired
    private ChineseExceptionUtils zh_ch;
    @Autowired
    private DocContentMapper docMapper;
    @Autowired
    private BCryptPasswordEncoderUtil bcrypt;

    /**
     * 查询指定文档
     *
     * @param logInName
     * @param parentMenu
     * @return
     */
    @Override
    @Log(type = FunctionType.List)
    public Result<Object> docData(String logInName, Object parentMenu) {
        try {
            List<DocContent> list = docContentMapper.selectDoc(logInName, parentMenu);
            return ResultUtil.success(ResultEnum.SUCCESS, list);
        } catch (Exception e) {
            return ResultUtil.error(ResultEnum.UNKONW_ERROR, e.getMessage().substring(0, 100));
        }
    }

    @Autowired
    private SysPermissionServiceImpl psi;

    /*查询文档列表*/
    @Override
    public Result<Object> getComputerFile(ClientParameters parameters) {
        try {
            Page<DocContent> page = new Page<>(parameters.getPage(), parameters.getLimit());
            IPage<DocContent> iPage = docContentMapper.getPageUser(page, parameters);
            return ResultUtil.success(ResultEnum.SUCCESS, iPage.getRecords(), iPage.getTotal());
        } catch (Exception e) {
            return ResultUtil.error(ResultEnum.UNKONW_ERROR, e.getMessage());
        }
    }

    /*添加*/
    @Override
    @Transactional
    public Result<Object> addComputerFile(DocContent docContent, MultipartFile file) {
        //文件名
        String file_name = ymlConfig.getResourceUrl() + docContent.getImgName() + ".jpg";
        docContent.setImgName("['" + docContent.getImgName() + "']");
        try {
            docMapper.insert(docContent);
            //1，上传文件
            File dest = new File(file_name);
            file.transferTo(dest);
            return ResultUtil.success(ResultEnum.SUCCESS);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(zh_ch.AddImage);
        }
    }

    /*修改*/
    @Override
    @Transactional
    public Result<Object> updComputerFile(DocContent docContent, MultipartFile file) {
        try {
            DocContent doc = docMapper.selectById(docContent.getId());
            if (doc == null) {
                throw new ServiceException(zh_ch.MissingParameters);
            } else
                //处理旧的图片名称
                doc.setImgName(doc.getImgName().substring(2, doc.getImgName().length() - 2));
            //处理新的图片名称
            String file_name = docContent.getImgName().startsWith("[") ? docContent.getImgName().substring(2, docContent.getImgName().length() - 2) : docContent.getImgName();
            if (EmptyUtils.isNotEmpty(file)) {
                FileUtil.del(ymlConfig.getResourceUrl() + doc.getImgName() + ".jpg");
                //1，上传文件
                File dest = new File(ymlConfig.getResourceUrl() + file_name + ".jpg");
                file.transferTo(dest);
            } else {
                FileUtil.rename(FileUtil.file(ymlConfig.getResourceUrl() + doc.getImgName() + ".jpg"), file_name + ".jpg", true);
            }
            //拼接图片名称加字符
            if (!docContent.getImgName().startsWith("["))
                docContent.setImgName("['" + docContent.getImgName() + "']");
            if (docContentMapper.updateById(docContent) > 0) {
                return ResultUtil.success(ResultEnum.SUCCESS);
            }
            throw new ServiceException(zh_ch.FailToEdit);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(zh_ch.FailToEdit);
        }
    }

    /*删除*/
    @Override
    @Transactional
    public Result<Object> delComputerFile(DocContent docContent) {
        if (docContent.getImgName().startsWith("[")) {
            docContent.setImgName(docContent.getImgName().substring(2, docContent.getImgName().length() - 2));
        }
        try {
            FileUtil.del(ymlConfig.getResourceUrl() + docContent.getImgName() + ".jpg");
            if (docContentMapper.deleteById(docContent.getId()) > 0) {
                return ResultUtil.success(ResultEnum.SUCCESS);
            }
            throw new ServiceException(zh_ch.FailedToDelete);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(zh_ch.FailedToDelete);
        }
    }


    @Override
    public void downloadDocumentation(ClientParameters parameters, HttpServletResponse response) {
        try {
            //文件路径
            String outputPath = DocPath + bcrypt.aesEncryption(parameters.getUgc()) + ".pdf";
            List<SysPermission> followNode = psi.menu(parameters);
            if (followNode.size() > 0) {
                if (!FileUtil.exist(outputPath)) {
                    XEasyPdfDocument pdfDocument = XEasyPdfHandler.Document.build();
                    //拼接图文集合
                    List<XEasyPdfComponent> componentList = new ArrayList<>();
                    //上一次总页数
                    int lastPage;
                    for (int p = 0; p < followNode.size(); p++) {
                        SysPermission sp = followNode.get(p);
                        if (sp.getChildren().size() > 0) {
                            //刷新(临时保存)
                            pdfDocument.flush();
                            lastPage = pdfDocument.getTotalPage();
                            //书签构建器
                            XEasyPdfDocumentBookmark.BookmarkNode bookmark = XEasyPdfDocumentBookmark.BookmarkNode.build();
                            componentList.add(     //拼接主菜单
                                    XEasyPdfHandler.Text.build(sp.getName())
                                            .setHorizontalStyle(XEasyPdfPositionStyle.RIGHT)
                                            .setMarginRight(30)
                                            // 设置字体大小
                                            .setFontSize(40F)
                                            // 设置字体颜色
                                            .setFontColor(new Color(1, 162, 212))
                                            // 使用粗体字
                                            .setDefaultFontStyle(XEasyPdfDefaultFontStyle.BOLD)
                            );

                            //构建主书签节点
                            bookmark.setTitle(sp.getName())
                                    .setPage(lastPage);
                            //二级菜单拼接
                            for (SysPermission spChildren : sp.getChildren()) {
                                List<DocContent> list = docContentMapper.selectDoc(parameters.getUgc(), spChildren.getId());
                                if (list.size() > 0) {
                                    componentList.add(
                                            XEasyPdfHandler.Text.build(spChildren.getName())
                                                    .setHorizontalStyle(XEasyPdfPositionStyle.CENTER)
                                                    // 设置字体大小
                                                    .setFontSize(35F)
                                                    .setFontColor(new Color(1, 71, 212))
                                                    // 使用粗体字
                                                    .setDefaultFontStyle(XEasyPdfDefaultFontStyle.NORMAL)
                                    );

                                    //构造书签子节点
                                    bookmark.addChild(
                                            XEasyPdfDocumentBookmark.BookmarkNode.build()
                                                    .setTitle(spChildren.getName())
                                                    .setPage(lastPage)
                                                    .setTop(500)
                                    );
                                    //内容拼接
                                    for (int i = 0; i < list.size(); i++) {
                                        DocContent doc = list.get(i);
                                        if (doc != null) {
                                            String imgName = doc.getImgName().substring(2, doc.getImgName().length() - 2);
                                            File file = new File(ymlConfig.getResourceUrl() + imgName + ".jpg");
                                            componentList.add(
                                                    XEasyPdfHandler.Text.build(NumbersToChinese.arabicNumToChineseNum(i + 1) + "·" + doc.getDocName())//标题
                                                            .setFontSize(30F)// 设置字体大小
                                                            .setDefaultFontStyle(XEasyPdfDefaultFontStyle.BOLD)// 使用粗体字
                                            );
                                            componentList.add(
                                                    XEasyPdfHandler.Text.build(doc.getDepict())//内容
                                                            .setFontSize(25F)// 设置字体大小
                                                            .setAutoIndent(2)
                                            );
                                            componentList.add(
                                                    XEasyPdfHandler.Image.build(file,
                                                            lengthWidth(file)[0],
                                                            lengthWidth(file)[1])
                                                            .setHorizontalStyle(XEasyPdfPositionStyle.CENTER)
                                                            .setMarginTop(10)
                                            );
                                            componentList.add(XEasyPdfHandler.Text.build(imgName)//标题
                                                    .setFontSize(25F)// 设置字体大小
                                                    .setHorizontalStyle(XEasyPdfPositionStyle.CENTER)
                                                    .setDefaultFontStyle(XEasyPdfDefaultFontStyle.LIGHT));
                                        }
                                    }
                                    //构建分割线
                                    componentList.add(
                                            XEasyPdfHandler.Text.build(
                                                    " '"
                                            ).setFontSize(20F).setMarginTop(30).setHorizontalStyle(XEasyPdfPositionStyle.CENTER).setFontColor(new Color(255, 255, 255))
                                    );
                                }
                            }

                            if (p == (followNode.size() - 1)) {
                                componentList.add(
                                        XEasyPdfHandler.SplitLine.SolidLine.build().setMarginTop(10F)
                                );
                                componentList.add(
                                        XEasyPdfHandler.Text.build("完结").setHorizontalStyle(XEasyPdfPositionStyle.CENTER)
                                );
                                componentList.add(
                                        XEasyPdfHandler.SplitLine.SolidLine.build().setMarginTop(10F)
                                );

                            }

                            XEasyPdfPage pdfPage = XEasyPdfHandler.Page.build(componentList);
                            componentList.clear();
                            PDRectangle rectangle = new PDRectangle(0f, 0f, 1665f, 2000f);
                            pdfDocument.addPage(pdfPage);
                            pdfDocument.modifyPageSize(rectangle, 0);
                            pdfDocument.setGlobalFooter(// 设置全局页脚
                                    XEasyPdfHandler.Footer.build(
                                            XEasyPdfHandler.Text.build("当前页码：" + XEasyPdfHandler.Page.getCurrentPagePlaceholder() + "     ")
                                                    .setHorizontalStyle(XEasyPdfPositionStyle.RIGHT)

                                    ));
                            //完成书签构建
                            pdfDocument.bookmark().setBookMark(bookmark).finish();
                        }

                    }
                    // 保存、关闭
                    pdfDocument.save(outputPath).close();
                }
                /*
                 * 返回文件流
                 */
                File file = new File(outputPath); // path是指想要下载的文件的路径
                // 获取文件名
                String filename = file.getName();
                byte[] buffer = FileUtil.readBytes(file);
                // 清空response
                response.reset();
                // 设置response的Header
                response.setCharacterEncoding("UTF-8");
                response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8));
                // 告知浏览器文件的大小
                response.addHeader("Content-Length", "" + file.length());
                response.addHeader("Content_name", filename);
                // 告知浏览器文件的大小
                response.addHeader("Content_size", "" + SizeConverter.transverter.BTrim.convert(file.length()));
                response.setContentType("application/pdf");
                OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
                outputStream.write(buffer);
                outputStream.flush();
            }
        } catch (Exception e) {
            throw new ServiceException(zh_ch.DownloadFailed);
        }
    }
}
